/**
 * elancom Corporation copy right 2012 - 2015  
 *   
 * $Header$
 * $Id$
 * $Author$
 * $Date$
 * $Revision$
 */
package com.elancom.framework.web;

import java.io.IOException;
import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.annotation.ModelAndViewResolver;

import com.elancom.framework.annotation.Ajax;
import com.elancom.framework.commons.json.JSON;
import com.elancom.framework.commons.json.serializer.SerializerFeature;
import com.elancom.framework.web.ui.JModel;
import com.elancom.framework.web.ui.JsonModel;
import com.elancom.framework.web.ui.Model;

/**
 * @author elancom
 * @date 2012-7-13
 */
public class CustomerModelAndViewResolver implements ModelAndViewResolver {

	/*
	 * (non-Javadoc)
	 * @see org.springframework.web.servlet.mvc.annotation.ModelAndViewResolver#resolveModelAndView(java.lang.reflect.Method, java.lang.Class, java.lang.Object,
	 * org.springframework.ui.ExtendedModelMap, org.springframework.web.context.request.NativeWebRequest)
	 */
	@Override
	public ModelAndView resolveModelAndView(Method handlerMethod, @SuppressWarnings("rawtypes") Class handlerType, Object returnValue,
			ExtendedModelMap implicitModel, NativeWebRequest webRequest) {
		boolean isAjaxRequest = "XMLHttpRequest".equals(webRequest.getHeader("X-Requested-With"));
		String json = null;

		if (returnValue != null) {
			// 两个条件
			if (returnValue instanceof JsonModel || (isAjaxRequest && !(returnValue instanceof String))) {
				json = parseJson(returnValue, webRequest);
			} else {
				webRequest.setAttribute("$output", returnValue, WebRequest.SCOPE_REQUEST);
			}
		}

		if (json != null) {
			HttpServletResponse response = (HttpServletResponse) webRequest.getNativeResponse();
			try {
				response.getWriter().write(json);
			} catch (IOException e) {
				e.printStackTrace();
			}
			return null;
		}

		if (returnValue == null) {
			Ajax ajax = AnnotationUtils.findAnnotation(handlerMethod, Ajax.class);
			if (ajax == null) {
				ajax = AnnotationUtils.findAnnotation(handlerType, Ajax.class);
			}

			if (ajax != null) {
				if (ajax.value()) {
					return null;
				}
			}
		}
		return UNRESOLVED;
	}

	private String parseJson(Object obj, NativeWebRequest webRequest) {
		HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
		System.out.println("--------------------------------------------------------------------------");
		String json = null;

		try {
			if (obj instanceof JModel) {
				json = ((JModel) obj).getJson();
			} else if (obj instanceof Model) {
				json = JSON.toJSONString(((Model) obj).getObject(), SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue);
			} else {
				json = JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteMapNullValue);
			}
			System.out.println("JSON序列成功:" + request.getRequestURI());
			System.out.println(json);
		} catch (Throwable e) {
			System.out.println("序列失败:" + request.getRequestURI());
			throw e;
		} finally {
			System.out.println("--------------------------------------------------------------------------");
		}

		return json != null ? json : "";
	}
}
